package com.gmail.blackdog1987.carcare.db;

import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.text.TextUtils;

/**
 * 
 * @author 董国超
 *
 */
public class DbHelper {

	/** 默认实例 */
	private static DbHelper sInstance = null;

	/** 数据库对象 */
	private SQLiteDatabase mSQLiteDb = null;
	/** 数据库打开助手对象 */
	private DbOpenHelper mOpenHelper = null;
	/** 上下文内容对象 */
	private Context mContext;

	private DbHelper(Context context) {
		mContext = context;
	}

	/**
	 * 获取默认实例。
	 * 
	 * @param context 上下文。
	 * @return 默认实例。
	 */
	public static DbHelper getDefault(Context context) {
		if (sInstance == null) {
			sInstance = new DbHelper(context);
		}
		return sInstance;
	}

	/**
	 * 打开数据库。
	 */
	public void open() {
		mOpenHelper = new DbOpenHelper(mContext);
		try {
			mSQLiteDb = mOpenHelper.getWritableDatabase();
		} catch (Exception e) {
			mSQLiteDb = mOpenHelper.getReadableDatabase();
		}
	}

	/**
	 * 获取 SQLiteDatabase。
	 * @return SQLiteDatabase。
	 */
	public SQLiteDatabase getSQLiteDatabase(){
		return mSQLiteDb;
	}

	/**
	 * 关闭数据库。
	 */
	public void close() {
		if (isOpen()) {
			mSQLiteDb.close();
			mSQLiteDb = null;
		}
	}

	/**
	 * 数据库是否打开。
	 * 
	 * @return 数据库打开返回true，否则返回false。
	 */
	public boolean isOpen() {
		if (mSQLiteDb == null) {
			return false;
		}
		return mSQLiteDb.isOpen();
	}

	/**
	 * 数据库是否为只读。
	 * 
	 * @return 数据库为只读返回true，否则返回false。
	 */
	public boolean isReadOnly() {
		return mSQLiteDb.isReadOnly();
	}

	/**
	 * 数据库是否被当前线程锁定。
	 * 
	 * @return 数据库被当前线程锁定返回true，否则返回false。
	 */
	public boolean isDbLockedByCurrentThread() {
		return mSQLiteDb.isDbLockedByCurrentThread();
	}

	/**
	 * 数据库是否被其他线程锁定。
	 * 
	 * @return 数据库被其他线程锁定返回true，否则返回false。
	 */
	@SuppressWarnings("deprecation")
	public boolean isDbLockedByOtherThreads() {
		return mSQLiteDb.isDbLockedByOtherThreads();
	}

	/**
	 * 启用安全锁。
	 * 
	 * @param lockingEnabled 是否启用安全锁。
	 */
	@SuppressWarnings("deprecation")
	public void setLockingEnabled(boolean lockingEnabled) {
		mSQLiteDb.setLockingEnabled(lockingEnabled);
	}

	/**
	 * 查询数据。
	 * 
	 * @param table 表名。
	 * @param columns 字段名（例：field1,field2）。
	 * @param selection 条件。
	 * @param selectionArgs 条件参数。
	 * @param groupBy 分组。
	 * @param having 子集限制。
	 * @param orderBy 排序。
	 * @param limit 数量限制（例：过20行取10行为10,20或10 offset 20）。
	 * @return 查询结果游标。
	 */
	public Cursor query(String table, String columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit) {
		String[] cols;
		if (TextUtils.isEmpty(columns) || "*".equals(columns)) {
			cols = null;
		} else {
			cols = columns.split(",");
		}
		return mSQLiteDb.query(table, cols, selection, selectionArgs, groupBy, having, orderBy, limit);
	}

	/**
	 * 查询数据。
	 * 
	 * @param table 表名。
	 * @param columns 字段名（例：String[]）。
	 * @param selection 条件。
	 * @param selectionArgs 条件参数。
	 * @param groupBy 分组。
	 * @param having 子集限制。
	 * @param orderBy 排序。
	 * @param limit 数量限制（例：过20行取10行为10,20或10 offset 20）。
	 * @return 查询结果游标。
	 */
	public Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit) {
		return mSQLiteDb.query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit);
	}
	
	/** 
	 * 查询数据。
	 * @param table 表名。
	 * @param columns 字段名（例：String[]）。
	 * @param selection 条件。
	 * @param selectionArgs 条件参数。
	 * @return 查询结果游标。
	 */
	public Cursor query(String table, String[] columns, String selection, String[] selectionArgs) {
		return mSQLiteDb.query(table, columns, selection, selectionArgs, null, null, null, null);
	}
	
	/** 
	 * @param table 表名。
	 * @param columns 字段名（例：String[]）。
	 * @param selection 条件。
	 * @param selectionArgs 条件参数。
	 * @return 查询结果游标。
	 */
	public Cursor query(String table, String columns, String selection, String[] selectionArgs) {
		String[] cols;
		if (TextUtils.isEmpty(columns) || "*".equals(columns)) {
			cols = null;
		} else {
			cols = columns.split(",");
		}
		return mSQLiteDb.query(table, cols, selection, selectionArgs, null, null, null, null);
	}

	/**
	 * 查询数据。
	 * 
	 * @param table 表名。
	 * @param columns 字段名（例：field1,field2）。
	 * @param selection 条件。
	 * @param orderBy 排序。
	 * @param limit 数量限制（例：过10行取20行为10,20或10 offset 20）。
	 * @return 查询结果游标。
	 */
	public Cursor query(String table, String columns, String selection, String orderBy, String limit) {
		String[] cols;
		if (TextUtils.isEmpty(columns) || "*".equals(columns)) {
			cols = null;
		} else {
			cols = columns.split(",");
		}
		return mSQLiteDb.query(table, cols, selection, null, null, null, orderBy, limit);
	}

	/**
	 * 查询数据。
	 * 
	 * @param table 表名。
	 * @param columns 字段名（例：field1,field2）。
	 * @param selection 条件。
	 * @param orderBy 排序。
	 * @return 查询结果游标。
	 */
	public Cursor query(String table, String columns, String selection, String orderBy) {
		String[] cols;
		if (TextUtils.isEmpty(columns) || "*".equals(columns)) {
			cols = null;
		} else {
			cols = columns.split(",");
		}
		return mSQLiteDb.query(table, cols, selection, null, null, null, orderBy);
	}

	/**
	 * 查询数据。
	 * 
	 * @param table 表名。
	 * @param columns 字段名（例：field1,field2）。
	 * @param selection 条件。
	 * @return 查询结果游标。
	 */
	public Cursor query(String table, String columns, String selection) {
		String[] cols;
		if (TextUtils.isEmpty(columns) || "*".equals(columns)) {
			cols = null;
		} else {
			cols = columns.split(",");
		}
		return mSQLiteDb.query(table, cols, selection, null, null, null, null);
	}

	/**
	 * 插入数据。
	 * 
	 * @param table 表名。
	 * @param values 字段和值。
	 * @return 插入数据的行id，若错误则返回-1。
	 */
	public long insert(String table, ContentValues values) {
		synchronized (this) {
			return mSQLiteDb.insert(table, null, values);
		}
	}

	/**
	 * 更新数据。
	 * 
	 * @param table 表名。
	 * @param values 字段和值。
	 * @param whereClause 条件。
	 * @return 被更新的行数。
	 */
	public int update(String table, ContentValues values, String whereClause) {
		synchronized (this) {
			return mSQLiteDb.update(table, values, whereClause, null);
		}
	}

	/**
	 * 更新数据。
	 * 
	 * @param table 表名。
	 * @param values 字段和值。
	 * @param whereClause 条件。
	 * @param whereArgs 参数。
	 * @return 被更新的行数。
	 */
	public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
		synchronized (this) {
			return mSQLiteDb.update(table, values, whereClause, whereArgs);
		}
	}

	/**
	 * 删除数据。
	 * 
	 * @param table 表名。
	 * @param whereClause 条件。
	 * @return 受影响的行数。
	 */
	public int delete(String table, String whereClause) {
		synchronized (this) {
			return mSQLiteDb.delete(table, whereClause, null);
		}
	}

	/**
	 * 删除数据
	 * 
	 * @param table 表名。
	 * @param whereClause 条件。
	 * @param whereArgs 参数。
	 * @return 受影响的行数。
	 */
	public int delete(String table, String whereClause, String[] whereArgs) {
		synchronized (this) {
			return mSQLiteDb.delete(table, whereClause, whereArgs);
		}
	}

	/**
	 * 执行SQL语句。
	 * 
	 * @param sql SQL语句。
	 */
	public void execSQL(String sql) {
		synchronized (this) {
			mSQLiteDb.execSQL(sql);
		}
	}

	/**
	 * 事务执行SQL语句。
	 * 
	 * @param sqlList SQL语句列表。
	 * @return 执行成功返回true，否则返回false。
	 */
	public boolean execSQLTransaction(List<String> sqlList) {
		synchronized (this) {
			boolean result = false;
			mSQLiteDb.beginTransaction();
			try {
				for (String sql : sqlList) {
					mSQLiteDb.execSQL(sql);
				}
				mSQLiteDb.setTransactionSuccessful();
				result = true;
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				mSQLiteDb.endTransaction();
			}
			return result;
		}
	}

	/**
	 * 事务执行SQL语句。
	 * 
	 * @param sqlArray SQL语句数组。
	 * @return 执行成功返回true，否则返回false。
	 */
	public boolean execSQLTransaction(String[] sqlArray) {
		synchronized (this) {
			boolean result = false;
			mSQLiteDb.beginTransaction();
			try {
				for (String sql : sqlArray) {
					mSQLiteDb.execSQL(sql);
				}
				mSQLiteDb.setTransactionSuccessful();
				result = true;
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				mSQLiteDb.endTransaction();
			}
			return result;
		}
	}

	/**
	 * 执行sql语句 返回游标。
	 * 
	 * @param sql SQL语句
	 * @return 结果集游标。
	 */
	public Cursor rawQuery(String sql) {
		synchronized (this) {
			return mSQLiteDb.rawQuery(sql, null);
		}
	}
}
